//
//  CLPagerViewLayout.h
//  Charles
//
//  Created by Leo on 2019/4/25.
//  Copyright © 2019 charles. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/**
 复用标识
 */
@interface NSObject (CL_PagerReuseIdentify)

@property (nonatomic, strong, readonly, nullable) NSString *cl_pagerReuseIdentify;

@end

@class CLPagerViewLayout<ItemType>;
@protocol CLPagerViewLayoutDataSource <NSObject>

- (NSInteger)numberOfItemsInPagerViewLayout;

- (id)pagerViewLayout:(CLPagerViewLayout *)pageViewLayout
         itemForIndex:(NSInteger)index
          prefetching:(BOOL)prefetching;

- (UIView *)pagerViewLayout:(CLPagerViewLayout *)pagerViewLayout
                viewForItem:(id)item
                    atIndex:(NSInteger)index;

- (void)pagerViewLayout:(CLPagerViewLayout *)pagerViewLayout
         addVisibleItem:(id)item
                atIndex:(NSInteger)index;

- (void)pagerViewLayout:(CLPagerViewLayout *)pagerViewLayout
    removeInVisibleItem:(id)item
                atIndex:(NSInteger)index;

@optional
- (UIViewController *)pagerViewLayout:(CLPagerViewLayout *)pagerViewLayout
                viewControllerForItem:(id)item
                              atIndex:(NSInteger)index;

@end

@protocol CLPagerViewLayoutDelegate <NSObject>

@optional

- (void)pagerViewLayout:(CLPagerViewLayout *)pagerViewLayout
    transitionFromIndex:(NSInteger) fromIndex
                toIndex:(NSInteger)toIndex
               animated:(BOOL)animated;

- (void)pagerViewLayout:(CLPagerViewLayout *)pagerViewLayout
    transitionFromIndex:(NSInteger) fromIndex
                toIndex:(NSInteger)toIndex
               progress:(CGFloat)progress;

- (void)pagerViewLayoutDidScroll:(CLPagerViewLayout *)pagerViewLayout;

- (void)pagerViewLayoutWillBeginScrollToView:(CLPagerViewLayout *)pagerViewLayout animate:(BOOL)animate;

- (void)pagerViewLayoutDidEndScrollToView:(CLPagerViewLayout *)pagerViewLayout animate:(BOOL)animate;;

- (void)pagerViewLayoutWillBeginDragging:(CLPagerViewLayout *)pagerViewLayout;

- (void)pagerViewLayoutDidEndDragging:(CLPagerViewLayout *)pagerViewLayout willDecelerate:(BOOL)decelerate;

- (void)pagerViewLayoutWillBeginDecelerating:(CLPagerViewLayout *)pagerViewLayout;

- (void)pagerViewLayoutDidEndDecelerating:(CLPagerViewLayout *)pagerViewLayout;

- (void)pagerViewLayoutDidEndScrollingAnimation:(CLPagerViewLayout *)pagerViewLayout;

@end

/**
 PagerView 布局
 */
@interface CLPagerViewLayout<__covariant ItemType> : NSObject

@property (nonatomic, weak, nullable) id<CLPagerViewLayoutDataSource> dataSource;
@property (nonatomic, weak, nullable) id<CLPagerViewLayoutDelegate>delegate;
@property (nonatomic, strong, readonly) UIScrollView *scrollView;
@property (nonatomic, assign) BOOL adjustScrollViewInset;
@property (nonatomic, assign, readonly) NSInteger countOfPagerItems;
@property (nonatomic, assign, readonly) NSInteger curIndex; // default :-1
@property (nonatomic, strong, readonly) NSCache <NSNumber *,ItemType> *memoryCache;
@property (nonatomic, assign) BOOL autoMemoryCache; // default : YES
@property (nonatomic, assign) NSInteger prefetchItemCount;
@property (nonatomic, assign) BOOL prefetchItemWillAddToSuperView;

@property (nonatomic, assign, readonly) NSRange prefetchRange;
@property (nonatomic, assign, readonly) NSRange visibleRange;
@property (nonatomic, strong, readonly, nullable) NSArray<NSNumber *> *visibleIndexs;
@property (nonatomic, strong, readonly, nullable) NSArray<ItemType> *visibleItems;
@property (nonatomic, assign) BOOL progressAnimateEnable;
@property (nonatomic, assign) BOOL addVisibleItemOnlyWhenScrollAnimatedEnd;
@property (nonatomic, assign) CGFloat changeIndexWhenScrollProgress;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

- (instancetype)initWithScrollView:(UIScrollView *)scrollView NS_DESIGNATED_INITIALIZER;

- (ItemType _Nullable)itemForIndex:(NSInteger)idx;

- (UIView *)viewForItem:(ItemType)item atIndex:(NSInteger)index;

- (UIViewController *_Nullable) viewControllerForItem:(id)item adIndex:(NSInteger)index;

- (CGRect)frameForItemAtIndex:(NSInteger)index;

- (void)registerClass:(Class)Class forItemWithReuseIdentifier:(NSString *)identifier;

- (void)registerNib:(UINib *)nib forItemWithReuseIdentifier:(NSString *)identifier;

- (ItemType)dequeueReusableItemWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index;

- (void)scrollToItemAtIndex:(NSInteger)index animate:(BOOL)animate;

- (void)updateData;

- (void)reloadData;

@end

NS_ASSUME_NONNULL_END
